/*
 * 
 * Proj. Wireless - UFRN
 * JFrameStep
 * 
 */

package gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import metodologia.DadosMetodologia;
import metodologia.Etapa;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTableHeader;

public class JFPStep extends javax.swing.JFrame {
    
    private String title; //Titulo do software
    
    // Variables Control
    private String name; // Nome do conjunto de etapas
    private ArrayList<Etapa> lEtapas1; // Array que armazena as etapas
    
    private int qtyBox;         // Variável que armazena a quantidade de etapas(checkboxs)
    private String tituloEtapa[];   //Vetor que armazena o título de cada etapa
    private String tDescript[];     //Vetor que armazena a descrição de cada etapa do teste
    private ArrayList<Integer> rowsTable;   //Vetor que armazena o numero de linhas da tabela
    private ArrayList<Integer> colTable;   //Vetor que armazena o numero de colunas da tabela
    private ArrayList<ArrayList<ArrayList<String>>> tableItens;    //Vetor que armazena as tabelas dos checkboxs.
    private ArrayList<ArrayList<String>> titleTable;
    private ArrayList<Boolean> active; //Variável que define se a tabela foi modificada ou continua em null
    
    private int progress;       // variável que armazena a quantidade de checkboxes marcados (progresso desta etapa)
    private int stage;          // variável para armazenar a que tópico da metodologia pertence esta tela    
    
    private boolean finished;
    
    // Variables Interface
    private JCheckBox cItens[]; // Vetor para os checkboxes que existem na tela
    private JPanel tItens[]; // Vetor para as tabelas de cada checkboxs
    
    private JPanel jplCheckBox; // Painel de CheckBoxs
    private JScrollPane jspCheckBox;
    private JPanel jplDescript; // Painel de Descrições de passos
    private JScrollPane jspDescript;
    private JTextArea jtaDescript;
    private JPanel jplTable; // Painel de tabela
    private JProgressBar jProgressBar1; // Barra de progresso
    private JTabbedPane jtpConfig; // Variável dos paneis de configuração
    private JButton jbFinished; // Botão de finalizar as etapas
    
    private JXTable table;
    private JScrollPane jspTable;
    private int numRows, numCol;

    /*
     * Construtor da classe
     */
    public JFPStep() {
        
        //Configuração da tela
        setLocationRelativeTo(null);
        ImageIcon imagemTituloJanela = new ImageIcon(getClass().getResource("/ImageFiles/icon_PW.png"));  
        setIconImage(imagemTituloJanela.getImage());
        title = "PW-Execute";
        setTitle(title);
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        
        //Inicialização de variáveis
        name = "";
        lEtapas1 = new ArrayList<Etapa>();
        qtyBox = 0;
        tituloEtapa = new String[qtyBox];
        tDescript = new String[qtyBox];
        rowsTable = new ArrayList<Integer>();
        colTable = new ArrayList<Integer>();

        initCount();
        initComponents();
        //onCloseWindows();
        
    }
    
    /*
     * Configura todos os checkboxs para marcados
     */
    public void setAllSelected(){
        for(int i=0; i<qtyBox; i++){
            cItens[i].setSelected(true);
        }
    }
    
    /*
     * Configura todos os checkboxs para não-marcados
     */
    public void setAllUnselected(){
        progress=0;
        for(int i=0; i<qtyBox; i++){
            cItens[i].setSelected(false);
        }
    }
    
    /*
     * Zera o progresso
     */
    private void initCount(){
        progress=0;
    }
    
    /*
     * Método que executa sempre que clicar no checkbox
     */
    private void clickedCheck(int i) {
        
        if (cItens[i].isSelected()){
            incProgress();
        }
        else{
            decProgress();
        }
        
        setProgress(i);
    }
    
    /*
     * Método que atualiza a barra de progresso 
     */
    private void setProgress(int i){
        
        int count = 0;
        for (int j=0; j<qtyBox; j++){
            if(cItens[j].isSelected()){
                count++;
            }
            else{
                break;
            }
        }
        jProgressBar1.setValue(count);
        
    }
    
    /*
     * Incrementa o valor do progresso
     */
    private void incProgress(){
        progress++;
    }
    
    /*
     * Decrementa o valor do progresso
     */
    private void decProgress(){
        progress--;
    }
    
    public int getProgress() {
        return progress;
    }
    
    /*
     * Evento para quando fechar a tela
     */
    private void onCloseWindows(){
        addWindowListener(new WindowAdapter() {  
            @Override
            public void windowClosed(WindowEvent e) { 
                check();
                if((progress == qtyBox)&&(qtyBox != 0)){
                    setFinished(true);
                }
                else {
                    setFinished(false);
                }
                
                setVisible(false);
            }  
        });
    }
    
    /*
     * Reconstrói o frame
     */
    private void constructFrame(){
        
        //Adiciona as características de cada checkboxs
        featuresCheckBox();
        
        //
        // Inicialização e configuração dos componentes
        //
        jplCheckBox = new JPanel(new GridLayout(0, 1, 5, 5));
        jspCheckBox = new JScrollPane(jplCheckBox, 
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        jspCheckBox.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "Etapas", 
            javax.swing.border.TitledBorder.LEFT, javax.swing.border.TitledBorder.DEFAULT_POSITION, 
            new java.awt.Font("Calibri", 1, 12), new java.awt.Color(0, 0, 0)));
        jspCheckBox.setPreferredSize(new Dimension(500, 350));
        jspCheckBox.setViewportView(jplCheckBox);
        
        jtaDescript = new JTextArea("");
        jspDescript = new JScrollPane(jtaDescript, 
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        jspDescript.setViewportView(jtaDescript);
        
        jplTable = new JPanel();
        jspTable = new JScrollPane(jplTable, 
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, 
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        table = new JXTable();
        
        jplTable.add(table);
        jspTable.setViewportView(jplTable);
        
        jProgressBar1 = new JProgressBar(0, qtyBox);
        jtpConfig = new JTabbedPane();
        
        jbFinished = new JButton("Finalizar");
        jbFinished.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jbFinishedActionPerformed(evt);
            }
        });
        
        //
        // Redesenhando o frame
        //
        setLayout(new BorderLayout());
        
        add(jspCheckBox, BorderLayout.NORTH);
        
        jtpConfig.addTab("Descrição", jspDescript);
        jtpConfig.addTab("Tabela", jspTable);
        
        add(jtpConfig);
        
        jProgressBar1.setPreferredSize(new Dimension(250 - jbFinished.getWidth(), 15));
        
        JPanel aux = new JPanel();
        aux.add(jProgressBar1);
        aux.add(jbFinished);
        
        add(aux, BorderLayout.SOUTH);
        
        pack();
        setSize(400, 600);
        
        // Métodos para adicionar as informações necessárias
        addCheckBoxs();
        
    }
    
    private void addListener(){
        int i;
        for(i=0; i<qtyBox; i++){
        final int aux = i;
        cItens[i].addMouseListener(new java.awt.event.MouseAdapter() {
                @Override
                public void mouseClicked(java.awt.event.MouseEvent evt){
                    jCheckBoxMouseClicked(evt, aux);
                }
                @Override
                public void mousePressed(java.awt.event.MouseEvent evt){
                    jCheckBoxMousePressed(evt, aux);
                }
                @Override
                public void mouseEntered(java.awt.event.MouseEvent evt){
                    jCheckBoxMouseEntered(evt, aux);
                }
            });
        }
    }
    
    /*
     * Atualiza o valor do progresso
     */
    private void check(){
        initCount();
        for(int i =0; i<cItens.length; i++){
            if (cItens[i].isSelected()) incProgress();
        }
    }
    
    private void jCheckBoxMouseClicked(java.awt.event.MouseEvent evt, int i) {
        
        clickedCheck(i);
        
        jplTable.removeAll();
        jplTable.add(tItens[i]);
        jplTable.repaint();
        jspTable.repaint();
        jtpConfig.repaint();
        
    }

    private void jCheckBoxMousePressed(java.awt.event.MouseEvent evt, int i) {
        
    }

    private void jCheckBoxMouseEntered(java.awt.event.MouseEvent evt, int i) {
        
        jtaDescript.setText(tDescript[i]);

    }
    
    /*
     * Método adiciona os checkboxs da tela
     */
    private void addCheckBoxs(){ 
        int i;
        Component[] listComponents;
        
        //Adiciona checkboxs a tela
        for(i=0; i<qtyBox; i++){
            JCheckBox cb = new JCheckBox(getTituloEtapa()[i]);
            jplCheckBox.add(cb);
        }
        jplCheckBox.repaint();
        
        //Recupera os checkboxs e coloca na várivel de armazenamento (cItens)
        listComponents = jplCheckBox.getComponents();        
        for(i=0; i<listComponents.length; i++){
            cItens[i] = (JCheckBox) listComponents[i];
        }
        
        //Adiciona as funcionalidades dos checkboxs
        addListener();
        
    }

    /*
     * Configura as características dos checkboxs,
     * por exemplo: descrição, tabela, observação etc.
     */
    private void featuresCheckBox(){
        
        JPanel aux;
        JXTable aux_table;
        JXTableHeader aux_header;
        
        //Adicionando as descrições(tdescript) de cada Etapa
        for(int i=0; i<lEtapas1.size(); i++){
            tituloEtapa[i] = lEtapas1.get(i).getTitulo();
            tDescript[i] = lEtapas1.get(i).getDescricao();
            if(lEtapas1.get(i).isPlanilha()){
                rowsTable.add(Integer.parseInt(lEtapas1.get(i).getnLinhas()));
                colTable.add(Integer.parseInt(lEtapas1.get(i).getnColunas()));
            } else{
                rowsTable.add(0);
                colTable.add(0);
                //System.out.println("-> Não tem planilha!");
            }
        }
        
        //Adicionando as tabelas de cada Etapa
        for(int i = 0; i<lEtapas1.size(); i++){
            if(lEtapas1.get(i).isPlanilha()){
                titleTable.add(lEtapas1.get(i).getTitulos());
                aux_table = new JXTable(rowsTable.get(i), colTable.get(i));
                for (int j = 0; j<rowsTable.get(i); j++){
                    for (int k = 0; k<colTable.get(i); k++){
                            aux_table.setValueAt("", j, k);
                    }
                }
                
                //Adicionando os titulos das colunas
                for(int j = 0; j<getTitleTable().get(i).size(); j++){
                    aux_table.getColumnModel().getColumn(j).setHeaderValue(getTitleTable().get(i).get(j));
                }
                aux_header = (JXTableHeader) aux_table.getTableHeader();
                aux = new JPanel(new BorderLayout());
                aux.add(aux_header, BorderLayout.NORTH);
                aux.add(aux_table, BorderLayout.CENTER);           
            } else{
                aux = new JPanel();               
            }
            
            tItens[i] = aux;
        }
        
    }
    
    /*
     * Evento do botão
     */
    private void jbFinishedActionPerformed(java.awt.event.ActionEvent evt) {                                         
        check();
        if(progress == qtyBox){
            setFinished(true);
        }
        else{
            setFinished(false);
        }
        
        setVisible(false);

    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 172, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 144, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    
//    public static void main(String args[]) {
//        /*
//         * Set the Nimbus look and feel
//         */
//        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
//        /*
//         * If Nimbus (introduced in Java SE 6) is not available, stay with the
//         * default look and feel. For details see
//         * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
//         */
//        try {
//            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
//                if ("Nimbus".equals(info.getName())) {
//                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
//                    break;
//                }
//            }
//        } catch (ClassNotFoundException ex) {
//            java.util.logging.Logger.getLogger(JFStep.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        } catch (InstantiationException ex) {
//            java.util.logging.Logger.getLogger(JFStep.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        } catch (IllegalAccessException ex) {
//            java.util.logging.Logger.getLogger(JFStep.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
//            java.util.logging.Logger.getLogger(JFStep.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
//        }
//        //</editor-fold>
//
//        /*
//         * Create and display the form
//         */
//        java.awt.EventQueue.invokeLater(new Runnable() {
//
//            public void run() {
//                new JFStep().setVisible(true);
//            }
//        });
//    }

    /*
     * Método que inicializa o frame com os dados entregue pelo frame-pai
     */
    private void boot(){
    
        qtyBox = lEtapas1.size();
        tituloEtapa = new String[qtyBox];
        tDescript = new String[qtyBox];
        rowsTable = new ArrayList<Integer>();
        colTable = new ArrayList<Integer>();
        
        tableItens = new ArrayList<ArrayList<ArrayList<String>>>();
        titleTable = new ArrayList<ArrayList<String>>();
        setActive(new ArrayList<Boolean>());
        
        setTitle(name + " - " + title);
        
        cItens = new JCheckBox[qtyBox];
        tItens = new JPanel[qtyBox];
        
        initCount();
        onCloseWindows();
        constructFrame();
        
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables

    public ArrayList<Etapa> getListaDeEtapas() {
        return lEtapas1;
    }

    public void setListaDeEtapas(ArrayList<Etapa> listaDeEtapas) {
        
        this.lEtapas1 = listaDeEtapas;
        
        //Inicializa o frame com seus dados
        boot();
        
    }
    
    public boolean isFinished() {
        check();
        if ((progress == qtyBox)&&(qtyBox != 0)) {
            finished = true;
        } else {
            finished = false;
        }
        return finished;
    }
    
    public void setFinished(boolean finished) {
        this.finished = finished;
    }
    
    public void setStage(int stage){
        this.stage=stage;
    }
    
    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }
    
    public boolean[] getListaDeCheckBox() {
        boolean[] c = new boolean[qtyBox];
        for(int i=0; i<qtyBox; i++){
            if (cItens[i].isSelected()) {
                c[i] = true;
            } else {
                c[i] = false;
            }
        }
        return c;
    }

    void setCheckBox(boolean[] b) {
        for (int i=0; i<qtyBox; i++) {
            if (b[i] == true) {
                cItens[i].setSelected(true);
            } else if (b[i] == false) {
                cItens[i].setSelected(false);
            }
        }
    }

    /**
     * @return the tableItens
     */
    public ArrayList<ArrayList<ArrayList<String>>> getTableItens() {
        
        boolean aux_teste;
        
        for (int i=0; i<qtyBox; i++) {
            //Array que armazena o array-de-colunas, array de linhas
            aux_teste = false;
            
            ArrayList<ArrayList<String>> aux2 = new ArrayList<ArrayList<String>>();
            for (int j = 0; j<rowsTable.get(i); j++) {
                //Array com as colunas - valores reais
                ArrayList<String> aux1 = new ArrayList<String>();
                for (int k = 0; k<colTable.get(i); k++){
                    aux1.add((String) ((JXTable) tItens[i].getComponent(1)).getValueAt(j, k));
                    if(((String) ((JXTable) tItens[i].getComponent(1)).getValueAt(j, k)) != null){
                        aux_teste = true;
                    }
                }
                aux2.add(aux1);
            }
            tableItens.add(aux2); 
            getActive().add(aux_teste);
        }
        
        return tableItens;
    }

    /**
     * @param tableItens the tableItens to set
     */
    public void setTableItens(ArrayList<ArrayList<ArrayList<String>>> tableItens) {

        this.tableItens = tableItens;
        
        for (int i=0; i<qtyBox; i++) {
            for (int j = 0; j<rowsTable.get(i); j++) {
                for (int k = 0; k<colTable.get(i); k++){
                    ((JXTable) tItens[i].getComponent(1)).setValueAt(tableItens.get(i).get(j).get(k), j, k);
                }
            }
        }
        
        jplTable.repaint();
        jspTable.repaint();
        jtpConfig.repaint();
    }

    /**
     * @return the titleTable
     */
    public ArrayList<ArrayList<String>> getTitleTable() {
        return titleTable;
    }

    /**
     * @param titleTable the titleTable to set
     */
    public void setTitleTable(ArrayList<ArrayList<String>> titleTable) {
        this.titleTable = titleTable;
    }

    /**
     * Retorna se a planilha foi modificada ou continua em null
     */
    public ArrayList<Boolean> getActive() {
        boolean aux_teste;
        
        for (int i=0; i<qtyBox; i++) {
            aux_teste = false;
            for (int j = 0; j<rowsTable.get(i); j++) {
                for (int k = 0; k<colTable.get(i); k++){
                    if(!((String) ((JXTable) tItens[i].getComponent(1)).getValueAt(j, k)).equals("")){
                        aux_teste = true;
                    }
                }
            }
            active.add(aux_teste);
        }
        
        return active;
    }

    /**
     * @param active the active to set
     */
    public void setActive(ArrayList<Boolean> active) {
        this.active = active;
    }
    
    public String getPorcentagem(){
        String porcentagem = "";
        int count = 0;
        for (int j=0; j<qtyBox; j++){
            if(cItens[j].isSelected()){
                count++;
            }
            
        }
        porcentagem = String.valueOf((count*100)/qtyBox);
        return porcentagem;
    }
    
    public String getCheckBoxMarcado() {
        String CheckBox = "";
        for (int j=0; j<qtyBox; j++){
            if(cItens[j].isSelected()) {
                CheckBox += "1";
            } else {
                CheckBox += "0";
            }
        }
        return CheckBox;
    }
    
    public int getQtyBox() {
        return qtyBox;
    }

    /**
     * @return the tituloEtapa
     */
    public String[] getTituloEtapa() {
        return tituloEtapa;
    }
}
